package io.itit.ecp.admin.provide.renderer;

import com.alibaba.fastjson.serializer.ValueFilter;
import io.itit.ecp.admin.common.enums.IEnergyTypeEnums;
import io.itit.ecp.admin.common.enums.IMeterDeviceEnums;
import io.itit.ecp.admin.provide.filter.IMeterDeviceFilter;
import io.itit.ecp.admin.server.entity.*;
import io.itit.ecp.admin.server.entity.extend.MeterDeviceExtEntity;
import io.itit.ecp.admin.server.service.*;
import io.itit.grass.common.server.utils.ConvertUtils;
import io.itit.grass.estelle.starter.parse.AbstractParseRenderer;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * @Author：Roy
 * @Description：计量设备管理导入解析器
 * @Date：Create by 2023-11-30 18:51:39
 */
@Scope("prototype")
@Component(MeterDeviceRenderer.ENTITY_NAME)
public class MeterDeviceRenderer extends AbstractParseRenderer<MeterDeviceExtEntity> {

    public static final String ENTITY_NAME = "meterDeviceRenderer";

    @Resource
    private ISceneRoomService sceneRoomService;
    @Resource
    private IMeterDeviceService meterDeviceService;

    @Resource
    private ISceneEdificeService sceneEdificeService;

    @Resource
    private ISceneProjectService sceneProjectService;

    @Resource
    private ISceneFloorService sceneFloorService;

    @Override
    public String entityName() {
        return ENTITY_NAME;
    }

    @Override
    public Class<MeterDeviceExtEntity> getClazz() {
        return MeterDeviceExtEntity.class;
    }

    @Override
    public ValueFilter getValueFilter() {
        return new IMeterDeviceFilter.MeterDeviceUploadFilter();
    }

    private Set<String> dataSet;
    private Set<String> keySet = new HashSet<>();

    @Override
    public int getHeadRowIndex() {
        return 1;
    }

    @Override
    public void processBefore() {
        dataSet = meterDeviceService.lambdaQuery().list()
                .stream().map(t -> t.getDeviceCode() +
                        t.getDeviceName() +
                        t.getMeterType() +
                        t.getPurpose())
                .collect(Collectors.toSet());
    }
    private String key(String deviceCode) {
        return deviceCode;
    }

    public void verify(MeterDeviceExtEntity entity) {

        IMeterDeviceEnums.DeviceType[] deviceType = IMeterDeviceEnums.DeviceType.values();
        IMeterDeviceEnums.MeterType[] meterType = IMeterDeviceEnums.MeterType.values();
        IMeterDeviceEnums.ReadMeterType[] readMeterType = IMeterDeviceEnums.ReadMeterType.values();
        IMeterDeviceEnums.ReadMeterTag[] readMeterTag = IMeterDeviceEnums.ReadMeterTag.values();
        IEnergyTypeEnums.Type[] type = IEnergyTypeEnums.Type.values();

        boolean flagDt = false;
        boolean flagMt = false;
        boolean flagRmt = false;
        boolean flagRtg = false;
        boolean flagTp = false;

    //查库
        SceneProjectEntity project = sceneProjectService.lambdaQuery()
                .eq(SceneProjectEntity::getProjectName, entity.getProjectName())
                .one();
        if (project == null){
            addErrorMsg("项目名称不存在!");
            return;
        }
        entity.setSceneProjectId(project.getId());

        SceneEdificeEntity edifice = sceneEdificeService.lambdaQuery()
                .eq(SceneEdificeEntity::getSceneProjectId, project.getId())
                .eq(SceneEdificeEntity::getEdificeName, entity.getEdificeName())
                .one();
        if (edifice == null){
            addErrorMsg("楼栋名称不存在");
            return;
        }
        entity.setSceneEdificeId(edifice.getId());
        entity.setEdificeName(edifice.getEdificeName());

        if(!(entity.getFloorName().equals(""))) {

            SceneFloorEntity floor = sceneFloorService.lambdaQuery()
                    .eq(SceneFloorEntity::getSceneEdificeId, edifice.getId())
                    .eq(SceneFloorEntity::getFloorName, entity.getFloorName())
                    .one();
            if (floor != null) {
                entity.setSceneFloorId(floor.getId());
                entity.setFloorName(floor.getFloorName());

                if(!(entity.getRoomName().equals(""))){

                    SceneRoomEntity room = sceneRoomService.lambdaQuery()
                        .eq(SceneRoomEntity::getSceneFloorId, floor.getId())
                        .eq(SceneRoomEntity::getRoomName, entity.getRoomName())
                        .one();
                    if (room != null) {
                    entity.setSceneRoomId(room.getId());
                     }
                    else {
                    addErrorMsg("空间名称不存在！");
                    }
                }
            }
            else {
                addErrorMsg("楼层名称不存在！");
            }
        }

        List<MeterDeviceEntity> code = meterDeviceService.lambdaQuery()
                .eq(MeterDeviceEntity::getDeviceCode, entity.getDeviceCode())
                .list();

//比对枚举
        for(IMeterDeviceEnums.DeviceType dt : deviceType){
            if (entity.getDeviceType().equals(dt.deviceType)){
                flagDt = true;
                break;
            }
        }
        if (flagDt){
            entity.setDeviceType(entity.getDeviceType());
        }else {
            addErrorMsg("设备不存在");
        }

        for(IMeterDeviceEnums.MeterType mt : meterType){
            if (entity.getMeterType().equals(mt.meterType)){
                flagMt = true;
                break;
            }
        }
        if (flagMt){
            entity.setMeterType(entity.getMeterType());
            for(IMeterDeviceEnums.ReadMeterType rmt : readMeterType){
                    if(entity.getReadMeterType().equals(rmt.readMeterType)){
                        flagRmt = true;
                        break;
                    }
            }
        }else {
            addErrorMsg("读表类型不存在！");
        }
        if (flagRmt){
            entity.setReadMeterType(entity.getReadMeterType());
        }
        else {
            addErrorMsg("二级类型不存在！");
        }

        for(IMeterDeviceEnums.ReadMeterTag rtg : readMeterTag){
            if(entity.getReadMeterTag().equals(rtg.readMeterTag)){
                flagRtg = true;
                break;
            }
        }

        if (flagRtg){
            entity.setReadMeterTag(entity.getReadMeterTag());
        }else {
            addErrorMsg("标识不存在！");
        }

        for(IEnergyTypeEnums.Type tp : type){
            if(entity.getEnergyTypeId().equals(tp.type)){
                flagTp = true;
                break;
            }
        }
        if (flagTp){
            entity.setEnergyTypeId(entity.getEnergyTypeId());
        }else {
            addErrorMsg("能源类型不存在！");
        }

//设置默认
            entity.setStatus(IMeterDeviceEnums.Status.status1.status);
            entity.setDelFlag(IMeterDeviceEnums.DelFlag.delFlag1.delFlag);


        addErrorMsg(entity.getDeviceCode()== null, "设备编码不能为空！");
        addErrorMsg(entity.getDeviceName() == null, "设备名称不能为空！");
        addErrorMsg(entity.getDeviceType() == null, "设备类型不能为空！");
        addErrorMsg(entity.getDeviceStatus() == null, "当前状态不能为空！");
        addErrorMsg(entity.getProjectName() == null,"所属项目不能为空!");
        addErrorMsg(entity.getEdificeName() == null , "楼栋名称不能为空！");
        addErrorMsg(entity.getMeterType() == null, "读表类型不能为空！");
        addErrorMsg(entity.getEnergyTypeId() == null, "能源类型不能为空！");
        addErrorMsg(entity.getReadMeterTag() == null, "读表标识不能为空！");
        addErrorMsg(entity.getPurpose() == null, "用途不能为空！");
        addErrorMsg(entity.getStatus() == null, "启用状态不能为空！");
        addErrorMsg(entity.getDelFlag() == null, "删除标识不能为空！");

        String key = key(entity.getDeviceCode());
        String message = "设备编码【" + entity.getDeviceCode()
                + "】设备名称【" + entity.getDeviceName();

        addErrorMsg(code.size() > 0, message + "】, 数据已存在！");
        addErrorMsg(keySet.contains(key), message + "】, 在导入文件中出现重复！");
        keySet.add(key);
    }

    @Override
    public int processAfter(List<MeterDeviceExtEntity> resultList) {
        if (CollectionUtils.isEmpty(resultList)) {
            return 0;
        }
        List<MeterDeviceEntity> entities = resultList.stream()
                        .map(ser-> ConvertUtils.copy(ser,MeterDeviceEntity.class))
                        .collect(Collectors.toList());
        meterDeviceService.saveMeterDeviceBatch(entities);
        return resultList.size();
    }
}
